<template>
  <div class="tag-cloud-3d-container">
    <div 
      class="tag-cloud-3d"
      ref="tagCloudRef"
      @mouseenter="onMouseEnter"
      @mouseleave="onMouseLeave"
      @touchstart="onTouchStart"
      @touchend="onTouchEnd"
      :style="{ transform: `perspective(${perspective}px)` }"
    >
      <div
        v-for="(tag, index) in tags"
        :key="tag.id || index"
        class="tag-item-3d"
        :style="getTagStyle(tag, index)"
        @click="handleTagClick(tag)"
      >
        {{ tag.name }}
        <span v-if="tag.count" class="tag-count">({{ tag.count }})</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';

// Props
const props = defineProps({
  tags: {
    type: Array,
    default: () => []
  },
  radius: {
    type: Number,
    default: 150
  },
  maxFontSize: {
    type: Number,
    default: 18
  },
  minFontSize: {
    type: Number,
    default: 12
  },
  autoRotate: {
    type: Boolean,
    default: true
  },
  rotateSpeed: {
    type: Number,
    default: 0.2
  },
  perspective: {
    type: Number,
    default: 1000
  },
  containerSize: {
    type: Number,
    default: 300 // 默认容器尺寸
  },
  // 新增圆心偏移属性
  centerOffsetX: {
    type: Number,
    default: -40 // X轴偏移量，正值向右，负值向左
  },
  centerOffsetY: {
    type: Number,
    default: 0 // Y轴偏移量，正值向下，负值向上
  }
});

// Emits
const emit = defineEmits(['tag-click']);

// Refs
const tagCloudRef = ref(null);
const rotationY = ref(45); // Y轴旋转
const rotationX = ref(-30); // X轴旋转，负角度使标签云朝上方倾斜
const rotationZ = ref(0); // 添加Z轴旋转以增加动态效果
const isAutoRotating = ref(props.autoRotate);
const autoRotateInterval = ref(null);
const tagPositions = ref({});
const isInteracting = ref(false); // 用于检测是否正在交互

// 计算每个标签的3D位置（考虑旋转）
const calculateTagPositions = () => {
  const positions = {};
  const count = props.tags.length;
  
  // 防止标签数量为0或1时的计算问题
  if (count === 0) return positions;
  
  props.tags.forEach((tag, index) => {
    // 使用黄金螺旋算法分布标签，实现更均匀的3D分布
    // 修复当count=1时的除零问题
    const y = count > 1 ? 1 - (index / (count - 1)) * 2 : 0; // y从1到-1
    const radius = Math.sqrt(1 - y * y); // 半径在y处的圆
    
    const theta = Math.PI * 2 * index * 0.618033988749895; // 黄金角度
    
    // 计算原始位置
    let x = Math.cos(theta) * radius;
    let z = Math.sin(theta) * radius;
    
    // 应用X轴、Y轴和Z轴旋转，但保持标签始终面向观察者
    const rotateYRad = (rotationY.value * Math.PI) / 180;
    const rotateXRad = (rotationX.value * Math.PI) / 180;
    const rotateZRad = (rotationZ.value * Math.PI) / 180;
    
    // 先应用Y轴旋转
    let rotatedX = x * Math.cos(rotateYRad) - z * Math.sin(rotateYRad);
    let rotatedZ = x * Math.sin(rotateYRad) + z * Math.cos(rotateYRad);
    let rotatedY = y;
    
    // 再应用X轴旋转
    const tempZ = rotatedZ;
    rotatedZ = rotatedZ * Math.cos(rotateXRad) - rotatedY * Math.sin(rotateXRad);
    rotatedY = tempZ * Math.sin(rotateXRad) + rotatedY * Math.cos(rotateXRad);
    
    // 最后应用Z轴旋转
    const tempX = rotatedX;
    rotatedX = rotatedX * Math.cos(rotateZRad) - rotatedY * Math.sin(rotateZRad);
    rotatedY = tempX * Math.sin(rotateZRad) + rotatedY * Math.cos(rotateZRad);
    
    // 计算标签大小（可选：根据文章数量调整大小）
    let fontSize = props.minFontSize;
    if (tag.count) {
      const countMin = Math.min(...props.tags.filter(t => t.count).map(t => t.count));
      const countMax = Math.max(...props.tags.filter(t => t.count).map(t => t.count));
      if (countMax > countMin) {
        fontSize = props.minFontSize + 
          (props.maxFontSize - props.minFontSize) * 
          ((tag.count - countMin) / (countMax - countMin));
      } else {
        fontSize = (props.minFontSize + props.maxFontSize) / 2;
      }
    }
    
    positions[index] = {
      x: rotatedX * props.radius,
      y: rotatedY * props.radius,
      z: rotatedZ * props.radius,
      fontSize: fontSize
    };
  });
  
  return positions;
};

// 自动旋转功能
const startAutoRotate = () => {
  if (autoRotateInterval.value) return;
  
  autoRotateInterval.value = setInterval(() => {
    if (isAutoRotating.value && !isInteracting.value) {
      // 修改自动旋转逻辑，同时旋转Y轴和Z轴，让所有标签都参与旋转
      rotationY.value = (rotationY.value + props.rotateSpeed) % 360;
      rotationZ.value = (rotationZ.value + props.rotateSpeed * 0.3) % 360; // Z轴旋转速度稍慢
      // 重新计算标签位置以应用旋转
      tagPositions.value = calculateTagPositions();
    }
  }, 50);
};

const stopAutoRotate = () => {
  if (autoRotateInterval.value) {
    clearInterval(autoRotateInterval.value);
    autoRotateInterval.value = null;
  }
};

// 鼠标进入容器
const onMouseEnter = () => {
  // 暂停自动旋转
  isInteracting.value = true;
};

// 鼠标离开容器
const onMouseLeave = () => {
  // 恢复自动旋转
  isInteracting.value = false;
};

// 触摸开始事件
const onTouchStart = () => {
  // 暂停自动旋转
  isInteracting.value = true;
};

// 触摸结束事件
const onTouchEnd = () => {
  // 恢复自动旋转
  isInteracting.value = false;
};

// 标签点击事件
const handleTagClick = (tag) => {
  emit('tag-click', tag);
};

// 监听标签数据变化
watch(() => props.tags, () => {
  tagPositions.value = calculateTagPositions();
}, { deep: true, immediate: true });

// 监听自动旋转设置变化
watch(() => props.autoRotate, (newVal) => {
  isAutoRotating.value = newVal;
});

// 监听旋转角度变化，重新计算位置
watch(rotationY, () => {
  tagPositions.value = calculateTagPositions();
});

// 添加对rotationX的监听
watch(rotationX, () => {
  tagPositions.value = calculateTagPositions();
});

// 添加对rotationZ的监听
watch(rotationZ, () => {
  tagPositions.value = calculateTagPositions();
});

// 获取单个标签的样式
const getTagStyle = (tag, index) => {
  const pos = tagPositions.value[index];
  if (!pos) return {};
  
  // 计算透明度和缩放，使其在Z轴方向上有远近效果
  const scale = (pos.z + props.radius) / (props.radius * 2);
  const opacity = 0.7 + scale * 0.3;
  
  return {
    position: 'absolute',
    top: '50%',
    left: '50%',
    transform: `translate3d(${-pos.x + props.centerOffsetX}px, ${-pos.y + props.centerOffsetY}px, ${pos.z}px)`,
    fontSize: `${pos.fontSize}px`,
    opacity: opacity,
    cursor: 'pointer',
    userSelect: 'none',
    whiteSpace: 'nowrap',
    pointerEvents: 'auto',
    zIndex: Math.round(pos.z + props.radius),
    // 移除固定颜色，使用CSS变量
    backfaceVisibility: 'hidden'
  };
};

// 生命周期钩子
onMounted(() => {
  tagPositions.value = calculateTagPositions();
  if (props.autoRotate) {
    startAutoRotate();
  }
});

onUnmounted(() => {
  stopAutoRotate();
});
</script>

<style scoped>
/* 定义CSS变量，用于不同主题模式 */
:root {
  --tag-text-color: #333;
  --tag-bg-color: rgba(255, 255, 255, 0.8);
  --tag-bg-hover-color: rgba(255, 255, 255, 1);
  --tag-border-color: rgba(0, 0, 0, 0.1);
  --tag-shadow-color: rgba(0, 0, 0, 0.1);
  --tag-shadow-hover-color: rgba(0, 0, 0, 0.2);
  --container-bg-color: transparent;
}

/* 深色模式样式 */
@media (prefers-color-scheme: dark) {
  :root {
    --tag-text-color: #e0e0e0;
    --tag-bg-color: rgba(30, 30, 30, 0.8);
    --tag-bg-hover-color: rgba(40, 40, 40, 1);
    --tag-border-color: rgba(255, 255, 255, 0.1);
    --tag-shadow-color: rgba(0, 0, 0, 0.3);
    --tag-shadow-hover-color: rgba(0, 0, 0, 0.5);
  }
}

.tag-cloud-3d-container {
  width: 100%;
  height: 100%;
  min-height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  touch-action: none;
  background-color: var(--container-bg-color);
}

.tag-cloud-3d {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 300px;
  min-width: 300px;
  transform-style: preserve-3d;
  transition: transform 0.1s ease-out;
}

.tag-item-3d {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 8px;
  border-radius: 12px;
  background-color: var(--tag-bg-color);
  backdrop-filter: blur(4px);
  box-shadow: 0 2px 8px var(--tag-shadow-color);
  will-change: transform, opacity;
  border: 1px solid var(--tag-border-color);
  color: var(--tag-text-color);
}

.tag-item-3d:hover {
  opacity: 1 !important;
  box-shadow: 0 4px 16px var(--tag-shadow-hover-color);
  background-color: var(--tag-bg-hover-color);
}
.tag-count {
  margin-left: 4px;
  font-size: 0.8em;
  opacity: 0.8;
}
</style>